package com.ruyue.csinstall.model.quote;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 默认的应用元数据，基于 Annotation
 */
public class DefaultAppMetadata implements AppMetadata {
    //
    private static final Log log =LogFactory.getLog(DefaultAppMetadata.class);
    //
    private File appDirectory;
    private AppClassLoader appClassLoader;
    //
    private Properties appProperties;
    private Set<String> servletClasses = new HashSet<String>();
    private Map<String, Set<String>> listenerClassesMap = new HashMap<String, Set<String>>();
    private Map<String, String> serviceServletMapping = new HashMap<String, String>();
    private Map<String, String> serviceMethodMapping = new HashMap<String, String>();
    //
    public DefaultAppMetadata(File appDirectory, AppClassLoader appClassLoader) throws IOException {
        initialize(appDirectory, appClassLoader);
    }

    public String getId() {
        return appDirectory.getName();
    }

    public String getName() {
        return appProperties.getProperty("app.name");
    }

    public String getVersion() {
        return appProperties.getProperty("app.version");
    }

    public String getContext() {
        return appProperties.getProperty("app.context");
    }

    public String[] getResolverClasses() {
        String appResolvers = appProperties.getProperty("app.resolvers");
        return StringUtils.commaDelimitedListToStringArray(appResolvers);
    }

    public Properties getProperties() {
        //
        Properties extraProperties = new Properties();
        for(Enumeration<?> e=appProperties.propertyNames(); e.hasMoreElements();) {
            String propertyName = (String) e.nextElement();
            String propertyValue = appProperties.getProperty(propertyName);
            extraProperties.setProperty(propertyName, propertyValue);
        }
        //
        return extraProperties;
    }

    public File getAppDirectory() {
        return appDirectory;
    }

    public AppClassLoader getClassLoader() {
        return appClassLoader;
    }

    public Set<String> getServletClasses() {
        return servletClasses;
    }

    public Set<String> getListenerClasses() {
        //
        Set<String> classSet = new HashSet<String>();
        for(Set<String> set : listenerClassesMap.values()) {
            classSet.addAll(set);
        }
        return classSet;
    }

    public Set<String> getListenerClassesOfType(String listenerTypeName) {
        Set<String> listenerClasses = listenerClassesMap.get(listenerTypeName);
        if (listenerClasses==null) {  // 避免调用者空指针异常
            listenerClasses = Collections.emptySet();
            listenerClassesMap.put(listenerTypeName, listenerClasses);
        }
        return listenerClasses;
    }

    public Map<String, String> getServiceServletMapping() {
        return serviceServletMapping;
    }

    public Map<String, String> getServiceMethodMapping() {
        return serviceMethodMapping;
    }

    private void initialize(File appDirectory, AppClassLoader appClassLoader) throws IOException {
        this.appDirectory = appDirectory;
        this.appClassLoader = appClassLoader;
        //
        Resource appPropertiesResource = new FileSystemResource(new File(appDirectory, "app.properties"));
        this.appProperties = PropertiesLoaderUtils.loadProperties(appPropertiesResource);
    }


}
